using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Xml;

namespace LevelEditor
{
    public static class IO
    {
        public static string currentDirectory;

        public static void Save(string filename)
        {
            string directoryName = Path.GetDirectoryName(filename);
            string worldName = Path.GetFileNameWithoutExtension(filename);

            XmlDocument doc = new XmlDocument();
            doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
            XmlElement root = doc.CreateElement("World");

            XmlElement nameNode = doc.CreateElement("Name");
            nameNode.InnerText = worldName;
            root.AppendChild(nameNode);

            XmlElement objectsNode = doc.CreateElement("Objects");
            {
                XmlElement playerNode = doc.CreateElement("Object");
                XmlElement positionNode = doc.CreateElement("Position");

                positionNode.Attributes.Append(doc.CreateAttribute("x"));
                positionNode.Attributes.Append(doc.CreateAttribute("y"));
                positionNode.Attributes.Append(doc.CreateAttribute("z"));
                playerNode.Attributes.Append(doc.CreateAttribute("Type"));

                positionNode.Attributes["x"].InnerText = "0";
                positionNode.Attributes["y"].InnerText = "0";
                positionNode.Attributes["z"].InnerText = "0";

                playerNode.Attributes["Type"].InnerText = "0";
                playerNode.AppendChild(positionNode);
                objectsNode.AppendChild(playerNode);
            }
            root.AppendChild(objectsNode);

            XmlElement heightmapNode = doc.CreateElement("Heightmap");
            {
                string heightmapFilename = worldName + "Height.hgt";
                HeightMap h = MainMenu.instance.viewWindow1.terrain.HeightMap;
                using (BinaryWriter writer = new BinaryWriter(new FileStream(Path.GetDirectoryName(filename) + "\\" + heightmapFilename, FileMode.OpenOrCreate)))
                {
                    Color[] data = new Color[h.vertexData.Width * h.vertexData.Height];
                    h.data.GetData(data);
                    for (int i = 0; i < h.data.Width * h.data.Height; i++)
                        writer.Write(data[i].ToVector4().W);

                    Vector4[] normalData = new Vector4[h.normalMap.Width * h.normalMap.Height];
                    h.normalMap.GetData(normalData);
                    for (int i = 0; i < normalData.Length; i++)
                    {
                        Vector4 v = normalData[i];
                        writer.Write(v.X);
                        writer.Write(v.Y);
                        writer.Write(v.Z);
                    }
                }

                heightmapNode.Attributes.Append(doc.CreateAttribute("Filename"));
                heightmapNode.Attributes["Filename"].Value = heightmapFilename;

                XmlElement highestElement = doc.CreateElement("Highest");
                XmlElement lowestElement = doc.CreateElement("Lowest");
                XmlElement widthElement = doc.CreateElement("Width");
                XmlElement heightElement = doc.CreateElement("Height");

                highestElement.InnerText = h.heighest.ToString();
                lowestElement.InnerText = h.lowest.ToString();
                widthElement.InnerText = h.MapWidth.ToString();
                heightElement.InnerText = h.MapHeight.ToString();

                heightmapNode.AppendChild(highestElement);
                heightmapNode.AppendChild(lowestElement);
                heightmapNode.AppendChild(widthElement);
                heightmapNode.AppendChild(heightElement);
            }
            root.AppendChild(heightmapNode);

            XmlElement lightingElement = doc.CreateElement("Lighting");
            {
                XmlElement lightsEnumerationElement = doc.CreateElement("Lights");
                /*add lighting shit here*/
                lightingElement.AppendChild(lightsEnumerationElement);
            }
            root.AppendChild(lightingElement);

            doc.AppendChild(root);

            
            doc.Save(filename);
        }

        public static void Load(string filename)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(new FileStream(filename, FileMode.Open));

            XmlNode root = doc.FirstChild;
            root = root.NextSibling;

            // TODO: load objects
            // TODO: load height map
            XmlNode heightMapNode = root.SelectSingleNode("Heightmap");
            {
                string heightFile = heightMapNode.Attributes["Filename"].InnerText;
                int highest = int.Parse(heightMapNode.SelectSingleNode("Highest").InnerText);
                int lowest = int.Parse(heightMapNode.SelectSingleNode("Lowest").InnerText);
                int width = int.Parse(heightMapNode.SelectSingleNode("Width").InnerText);
                int height = int.Parse(heightMapNode.SelectSingleNode("Height").InnerText);

                HeightMap h = new HeightMap(width, height, lowest, highest, MainMenu.instance.graphics.device);

                Color[] hightData = new Color[h.vertexData.Width * h.vertexData.Height];
                Vector4[] normalData = new Vector4[h.vertexData.Width * h.vertexData.Height];
                using (BinaryReader reader = new BinaryReader(new FileStream(Path.GetDirectoryName(filename) + "\\" + heightFile, FileMode.Open)))
                {
                    for (int i = 0; i < hightData.Length; i++)
                        hightData[i] = Color.Black * reader.ReadSingle();
                

                    for (int i = 0; i < normalData.Length; i++)
                    {
                        normalData[i].X = reader.ReadSingle();
                        normalData[i].Y = reader.ReadSingle();
                        normalData[i].Z = reader.ReadSingle();
                    }
                }

                h.data.SetData(hightData);
                h.normalMap.SetData(normalData);

                h.Update();

                MainMenu.instance.viewWindow1.terrain.HeightMap = h;
            }
            // TODO: load lighting
        }
    }
}